<template>
  <div class="share-circle-content w-1200">
    <div class="circle-block-list">
      <div class="block-content">
        <div class="item" :class="{ selected: !currentBlock }" @click="handleSelectBlockCircle('')">
          <img src="~/assets/images/new.svg" alt="">
          <p style="margin-left: 11px;">最新</p>
        </div>
        <div
          class="item"
          :class="{ selected: item.id === currentBlock }"
          v-for="item in blockList"
          :key="item.id"
          @click="handleSelectBlockCircle(item.id)">
          <img src="~/assets/images/color_blocks.svg" alt="">
          <p>{{ item.name }}</p>
        </div>
      </div>
    </div>
    <div class="left-share-modal">
      <!-- 友圈分享发布模块 -->
      <div class="publish-block">
        <div class="input-block">
          <textarea
            id="shareInput"
            v-model="content"
            class="rich-editor gloab-scroll-bar"
            :rows="5"
            :maxlength="512"
            placeholder="快来分享你的新鲜事吧~"
          ></textarea>
          <a-upload
            v-if="fileList.length"
            action="#"
            list-type="picture-card"
            :file-list="fileList"
            :before-upload="beforeImageUpload"
            :custom-request="customHttpRequest"
            :remove="handleRemove"
            @preview="handlePreview"
          >
            <div v-if="fileList.length < 3">
              <a-icon type="plus" />
              <div class="ant-upload-text">Upload</div>
            </div>
          </a-upload>
        </div>
        <div class="publish-group">
          <div class="left-gropu">
            <EmojiPicker @select="selectEmoji" />
            <a-upload
              name="file"
              supportServerRender
              :before-upload="beforeImageUpload"
              :custom-request="customHttpRequest"
              action="#"
            >
              <p class="select-pic"><i class="ri-folder-image-line"></i>图片</p>
            </a-upload>
            <a-popover placement="bottom" trigger="focus">
              <template slot="content">
                <div class="popover-block-select">
                  <p
                    @click="uploadBlockId = item.id"
                    v-for="item in blockList"
                    :key="item.id">{{ item.name }}</p>
                </div>
              </template>
              <button class="select-block-btn">
                <img src="~/assets/images/color_blocks.svg" alt="">
                <p>{{ circleBlockMap[uploadBlockId] }}</p>
                <i class="ri-arrow-down-s-line"></i>
              </button>
            </a-popover>
          </div>
          <div>
            <a-button
              :disabled="!content.replace(/\s/g, '')"
              :loading="publishLoading"
              type="primary"
              @click="publishShareCircle"
              >发布</a-button
            >
          </div>
        </div>
      </div>
      <div
        v-if="!pagination.list.length"
        style="padding: 30px 0; background: #fff"
      >
        <a-empty
          description="暂无数据"
          :image="require('~/assets/images/nodata.png')"
        />
      </div>
      <div v-else class="shart-list-block">
        <div
          v-for="item in pagination.list"
          :key="item.id"
          class="share-block"
        >
          <div class="top">
            <HeadAvatar :to="`/user/${item.userId}`" :width="40" :height="40" :img="item.avatar" />
            <div class="right-info">
              <p class="nickname">
                <nuxt-link target="_blank" :to="`/user/${item.userId}`">{{
                  item.nickname
                }}</nuxt-link>
              </p>
              <p class="desc">
                <span v-if="item.job">{{ item.job }} · </span
                >{{ cycleDate(item.createTime) }}
              </p>
              <p class="share-info">{{ item.hasLimit && item.toggle ? item.limitContent : item.content }}</p>
              <div
                class="limit-box"
                v-if="item.hasLimit">
                <span @click="item.toggle = !item.toggle">{{ item.toggle ? '展开' : '收起' }}</span>
              </div>
              <div v-if="item.picList && item.picList.length" class="img-box">
                <div
                  v-for="itemName in item.picList"
                  :key="itemName"
                  class="share-img"
                  @click="handlePreview({ url: itemName })"
                >
                  <img :src="itemName" alt="shareImg" />
                </div>

              </div>
              <div class="circle-block-name">
                <img src="~/assets/images/color_blocks.svg" alt="">
                <p>{{ circleBlockMap[item.block] }}</p>
              </div>
            </div>
          </div>
          <div class="agree-users" v-if="item.agreeUsers.length">
            <div class="agree-users-modal">
              <div
                class="single-user"
                v-for="(itemName, idx) in item.agreeUsers"
                :key="idx"
                :style="{ right: idx * 14 + 'px' }">
                <img :src="itemName.avatar || 'https://image.zdxblog.cn/picture/16849805191921684980519192.png'" alt="avatar">
              </div>
            </div>
            <p>{{ item.agreeUsers.length === 5 ? '等人' : '' }}赞过</p>
          </div>
          <div class="bottom">
            <div
              :class="{ like: item.replyState }"
              @click="item.replyState = !item.replyState"
            >
              <i v-if="!item.replyState" class="ri-message-ai-3-line"></i>
              <i v-else class="ri-volume-up-line"></i>
              <span v-if="item.commentCount">{{ item.commentCount }}</span>
            </div>
            <div :class="{ like: item.isLiker }" @click="isLikeCircle(item)">
              <i class="ri-thumb-up-line"></i>
              <span v-if="item.agreeCount">{{ item.agreeCount }}</span>
            </div>
          </div>
          <SimpleComment
            v-if="item.replyState"
            :circie-user-id="item.userId"
            :circle-id="item.id"
          />
        </div>
      </div>
    </div>
    <div class="right-data-modal">
      <div style="position: sticky; top: 73px;">
        <div class="user-modal">
          <div class="profile">
            <HeadAvatar
              :width="42"
              :height="42"
              :img="!userInfo ? require('~/assets/images/default.svg') : userInfo.avatar || 'https://image.zdxblog.cn/picture/16849805191921684980519192.png'"/>
            <div class="user-info">
              <p class="nickname">
                <span v-if="userInfo">{{ userInfo.nickname }}</span>
                <em v-else @click="$store.commit('UPDATE_LOGIN_VISIBLE', true)">登录/注册</em>
              </p>
              <p class="job"> {{ userInfo ? userInfo.job || '' : '即刻玩转友圈' }}</p>
            </div>
          </div>
          <div class="statistics">
            <div @click="userRouteLink('/circle')">
              <p>友圈</p>
              <span>{{
                staticsCount.shareCount === undefined
                  ? '-'
                  : staticsCount.shareCount
              }}</span>
            </div>
            <div @click="userRouteLink('/focus')">
              <p>关注</p>
              <span>{{
                staticsCount.focusCount === undefined
                  ? '-'
                  : staticsCount.focusCount
              }}</span>
            </div>
            <div @click="userRouteLink('/focus')">
              <p>粉丝</p>
              <span>{{
                staticsCount.focusedCount === undefined
                  ? '-'
                  : staticsCount.focusedCount
              }}</span>
            </div>
          </div>
        </div>
        <div class="recommand-hot-news">
          <div class="title">
            <p class="linear-border-bottom">
              <img src="@/assets/images/hot1.png" alt="">
              <em @click="updatePageNews">换一换</em>
            </p>
          </div>
          <div class="content">
            <a-spin v-show="loading" style="position: absolute; top: 50%; left: 50%; transform: translateX(-50%);">
              <a-icon slot="indicator" type="loading" style="font-size: 24px" spin />
            </a-spin>
            <ul>
              <li v-for="(item, index) in hotNews.slice(newSize - 10, newSize)" :key="index">
                <span
                  :class="{
                    first: index === 0 && newSize === 10,
                    second: index === 1 && newSize === 10,
                    third: index === 2 && newSize === 10,
                  }">{{ index + 1 + ((newSize - 10) / 10) * 10 }}</span>
                <a :href="item.url" target="_blank">{{ item.title }}</a>
                <em>{{ item.hot | splitNumber }}</em>
              </li>
            </ul>
            <div v-if="!hotNews.length" style="padding-top: 90px;">
              <a-empty
                description="暂无热点数据"
                :image="require('~/assets/images/nodata.png')"
                :imageStyle="{ width: '80px', margin: '0 auto' }"
              />
            </div>
          </div>
        </div>
        <div style="margin-top: 10px;">
          <SiteCopyRight />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import { getBase64, cycleDate } from '~/util'
import EmojiPicker from '~/components/EmojiPicker'
import ScrollLoadEvent from '~/util/scrollLoadEvent'
import SiteCopyRight from '~/components/SiteCopyRight'
import { CIRCLE_BLOCKS, circleBlockMap } from '~/config/optionMap'
import SimpleComment from './components/SimpleComment'

const newType = ['itNews', 'toutiao', 'baiduRD', 'zhihuDay', 'douyinHot', 'huXiu', 'pengPai', 'woShiPm']
export default {
  name: 'ShareCircle',
  components: { EmojiPicker, SimpleComment, SiteCopyRight },
  layout: 'BaseLayout',
  async asyncData ({ $axios }) {
    try {
      const [pageNo, pageSize] = [1, 10]
      const { data } = await $axios.get(`/gimishare/api/v1/shares?pageNo=${pageNo}&pageSize=${pageSize}`)
      const list = data.list.map(o => {
        const limitContent = o.content?.substring(0, 118).split('\r\n').slice(0, 4).join('\r\n')
        return {
          ...o,
          replyState: false,
          limitContent: limitContent + ' ...',
          hasLimit: limitContent !== o.content,
          toggle: true
        }
      })
      return {
        pagination: { ...data, list, pageSize }
      }
    } catch (error) {
      console.log(error)
    }
  },
  data () {
    return {
      circleBlockMap,
      cycleDate,
      blockList: CIRCLE_BLOCKS,
      content: '',
      fileList: [],
      publishLoading: false,
      staticsCount: '',
      scrollLoadEvent: null,
      pagination: { pageNo: 1, pageSize: 20, list: [], total: 0 },
      hotNews: [],
      newSize: 10,
      newTypeIdx: 0,
      loading: false,
      currentBlock: '',
      uploadBlockId: '1'
    }
  },

  head () {
    return {
      title: '友圈分享 - GimiShare',
      meta: [
        { charset: 'utf-8' },
        {
          hid: 'description',
          name: 'description',
          content: 'GimiShare，友圈分享'
        }
      ]
    }
  },

  computed: {
    ...mapState({
      userInfo: (state) => state.userInfo
    })
  },

  watch: {
    userInfo: {
      handler (newval) {
        newval && this.getUserStatistics()
      },
      deep: true,
      immediate: true
    }
  },

  created () {
    this.queryHotNewList()
    this.scrollLoadEvent = new ScrollLoadEvent(
      this.scrollLoadShareCircle.bind(this)
    )
    if (process.browser) {
      this.$nextTick(() => {
        this.scrollLoadEvent.bindScrollEvent()
      })
    }
  },

  beforeDestroy () {
    this.scrollLoadEvent.removeScrollEvent()
  },

  methods: {
    /**
     * scroll load shareCircle list
     */
    async scrollLoadShareCircle () {
      this.scrollLoadEvent.loadState = false
      try {
        this.pagination.pageNo++
        const { pageNo, pageSize } = this.pagination
        const { data } = await this.$axios.get(`/gimishare/api/v1/shares?pageNo=${pageNo}&pageSize=${pageSize}&block=${this.currentBlock}`)
        this.pagination.list.push(
          ...data.list.map((o) => {
            const limitContent = o.content?.substring(0, 118).split('\r\n').slice(0, 4).join('\r\n')
            return {
              ...o,
              replyState: false,
              limitContent: limitContent + ' ...',
              hasLimit: limitContent !== o.content,
              toggle: true
            }
          })
        )
        if (pageNo >= Math.ceil(data.total / pageSize)) {
          this.scrollLoadEvent.loadState = false
        } else {
          this.scrollLoadEvent.loadState = true
        }
      } catch (error) {
        this.scrollLoadEvent.loadState = true
      }
    },

    handleSelectBlockCircle (blobkId) {
      this.currentBlock = blobkId
      this.scrollLoadEvent.loadState = true
      this.pagination.list = []
      this.pagination.pageNo = 0
      this.scrollLoadShareCircle()
    },

    /**
     * publish share circle
     */
    async publishShareCircle () {
      if (!this.userInfo) {
        return this.$store.commit('UPDATE_LOGIN_VISIBLE', true)
      }
      if (this.content || this.publishLoading) {
        this.publishLoading = true
        const data = new FormData()
        data.append('content', this.content)
        data.append('block', this.uploadBlockId)
        this.fileList.forEach((file) => {
          data.append('file', file)
        })
        try {
          await this.$axios.post('/gimishare/api/v1/shares/createshare', data)
          this.content = ''
          this.fileList = []
          this.pagination.list = []
          this.pagination.pageNo = 0
          this.currentBlock && (this.currentBlock = this.uploadBlockId)
          this.scrollLoadShareCircle()
          this.$message.success('发布友圈成功')
        } catch (error) {
          console.log(error)
        } finally {
          this.publishLoading = false
        }
      }
    },

    /**
     * user like or unlike sharecircle
     * @param { Object } circleItem
     */
    async isLikeCircle (circleItem) {
      if (!this.userInfo) {
        return this.$store.commit('UPDATE_LOGIN_VISIBLE', true)
      }
      try {
        const API = circleItem.isLiker ? '/shares/unagree' : '/shares/agree'
        await this.$axios.get(
          `/gimishare/api/v1${API}?id=${circleItem.id}&uid=${circleItem.userId}`
        )
        if (circleItem.isLiker) {
          circleItem.agreeCount -= 1
        } else {
          circleItem.agreeCount += 1
        }
        circleItem.isLiker = !circleItem.isLiker
      } catch (error) {}
    },

    async getUserStatistics () {
      try {
        const { data } = await this.$axios.get(
          `/gimishare/api/v1/users/getcounts?userId=${this.userInfo.id}`
        )
        this.staticsCount = data
      } catch (error) {
        console.log(error)
      }
    },

    /**
     * select emoji
     * @param { Object } emoji
     * @param { Object } commentItem
     */
    selectEmoji (emoji) {
      const input = document.getElementById('shareInput')
      const startPos = input.selectionStart
      const endPos = input.selectionEnd
      const resultText =
        input.value.substring(0, startPos) +
        emoji.data +
        input.value.substring(endPos)
      input.value = resultText
      input.focus()
      input.selectionStart = startPos + emoji.data.length
      input.selectionEnd = startPos + emoji.data.length
      this.content = resultText
    },

    userRouteLink (path) {
      if (!this.userInfo) {
        return this.$store.commit('UPDATE_LOGIN_VISIBLE', true)
      }
      this.$router.push(`/user/${this.userInfo.id}${path}`)
    },

    async customHttpRequest ({ file }) {
      const picSrc = await getBase64(file)
      file.url = picSrc
      this.fileList = [...this.fileList, file]
    },

    handleRemove (file) {
      const index = this.fileList.indexOf(file)
      const newFileList = this.fileList.slice()
      newFileList.splice(index, 1)
      this.fileList = newFileList
    },

    async queryHotNewList () {
      this.loading = true
      try {
        const hotNews = await this.$axios.get(
          `/gimishare/api/v1/unit/hot-news?type=${newType[this.newTypeIdx]}`
        )
        this.hotNews = hotNews.data
        this.newSize = 10
      } finally {
        this.loading = false
      }
    },

    async updatePageNews () {
      if (this.loading) return
      this.newSize += 10
      if (this.newSize > 30 || this.hotNews.slice(this.newSize - 10, this.newSize).length === 0) {
        this.newTypeIdx += 1
        if (this.newTypeIdx === newType.length) {
          this.newTypeIdx = 0
        }
        this.queryHotNewList()
      }
    },

    beforeImageUpload (file) {
      const fileType = file.name
        .substring(file.name.lastIndexOf('.') + 1)
        .toLowerCase()
      if (!['jpeg', 'jpg', 'svg', 'gif', 'png', 'webp'].includes(fileType)) {
        this.$message.error('上传图片格式不正确')
        return false
      }
      const isLt5M = file.size / 1024 / 1024 < 5
      if (!isLt5M) {
        this.$message.error('上传头图片大小不能超过 5MB!')
        return false
      }
      return true
    },

    handlePreview (file) {
      this.$store.commit('UPDATE_PREVIEW_IMGSRC', file.url)
    }
  }
}
</script>

<style scoped lang="less">
.share-circle-content {
  margin-top: 12px;
  padding-bottom: 30px;
  display: flex;
  .circle-block-list {
    width: 200px;
    .block-content {
      position: sticky;
      top: 73px;
      background: #fff;
      border-radius: 4px;
      padding: 20px 12px 12px;
      .item {
        height: 42px;
        display: flex;
        align-items: center;
        padding: 0 12px;
        border-radius: 4px;
        margin-bottom: 4px;
        cursor: pointer;
        font-size: 0;
        &:hover {
          background: var(--alaph-primary-color);
        }
        p {
          color: #000;
          font-size: 13px;
          margin-left: 8px;
        }
        img {
          height: 26px;
        }
        &.selected {
          background: var(--select-primary-color);
          p {
            color: var(--primary-color);
          }
        }
      }
    }
  }
  .left-share-modal {
    width: 688px;
    margin: 0 12px;
    .publish-block {
      position: relative;
      background: #fff;
      border-radius: 4px;
      padding: 20px;
      margin-bottom: 12px;
      .input-block {
        background: #f2f3f5;
        border-radius: 4px;
        overflow: hidden;
        textarea {
          width: 100%;
          display: block;
          border-radius: 4px;
          padding: 12px;
          resize: none;
          border: 1px solid transparent;
          outline: none;
          background: transparent;
          color: #4c4c4c;
          transition: .3s;
          &:focus {
            border-color: var(--primary-color);
          }
        }
      }
      .publish-group {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-top: 6px;
        .left-gropu {
          display: flex;
          align-items: center;
          .select-pic {
            margin-left: 20px;
            cursor: pointer;
            font-size: 12px;
            display: flex;
            align-items: center;
            i {
              font-size: 20px;
              vertical-align: middle;
              margin-right: 4px;
            }
          }
          .select-block-btn {
            display: inline-flex;
            font-size: 0;
            background-color: #fff;
            align-items: center;
            cursor: pointer;
            margin-left: 12px;
            position: absolute;
            bottom: 65px;
            right: 28px;
            padding: 2px 8px;
            border-radius: 16px;
            border: none;
            outline: none;
            img {
              width: 20px;
            }
            p {
              font-size: 12px;
              color: var(--primary-color);
            }
            i {
              font-size: 18px;
              color: var(--primary-color);
              position: relative;
              top: 2px;
            }
          }
        }
      }
    }
    .shart-list-block {
      .share-block {
        border-radius: 4px;
      }
    }
  }
  .right-data-modal {
    flex: 1;
    .user-modal {
      background: #fff;
      padding: 20px;
      border-radius: 4px;
      .profile {
        display: flex;
        align-items: center;
        .user-info {
          width: 0;
          flex: 1;
          padding-left: 10px;
          .nickname {
            em {
              color: var(--primary-color);
              cursor: pointer;
              font-style: normal;
              font-size: 13px;
            }
            span {
              color: #000;
            }
          }
          .job {
            color: #999;
            font-size: 12px;
          }
        }
      }
      .statistics {
        margin-top: 20px;
        display: flex;
        & > div {
          width: 100%;
          cursor: pointer;
          text-align: center;
          p {
            color: #000;
            margin-bottom: 4px;
          }
          span {
            color: #999;
            font-size: 16px;
          }
        }
      }
    }
    .recommand-hot-news {
      background: #fff;
      border-radius: 4px;
      margin-top: 10px;
      .title {
        padding: 0 20px;
        p {
          height: 42px;
          display: flex;
          align-items: center;
          justify-content: space-between;
          img {
            height: 14px;
          }
          em {
            cursor: pointer;
            color: #999;
            font-style: normal;
            font-size: 11px;
            user-select: none;
            &:active {
              opacity: .6;
            }
          }
        }
      }
      .content {
        height: 316px;
        ul {
          list-style: none;
          margin: 0;
          padding: 8px 0;
          li {
            padding: 6px 20px;
            font-size: 12px;
            display: flex;
            align-items: center;
            span {
              width: 16px;
              height: 16px;
              line-height: 16px;
              font-size: 11px;
              background: #ccc;
              border-radius: 2px;
              color: #fff;
              text-align: center;
              &.first {
                background: #c91616;
              }
              &.second {
                background: #11c693;
              }
              &.third {
                background: #e17317;
              }
            }
            a {
              color: #4c4c4c;
              flex: 1;
              width: 0;
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
              margin: 0 8px;
              &:hover {
                color: var(--primary-color);
              }
            }
            em {
              color: #999;
              font-style: normal;
              flex-shrink: 0;
            }
          }
        }
        ::v-deep .ant-empty {
          &-image {
            height: auto;
            img {
              width: 100%;
              height: auto;
            }
          }
          &-description {
            font-size: 12px;
            color: #999;
            margin-top: 6px;
          }
        }
      }
    }
  }
}
</style>
